package main.test.SparkAPI.Baics.game.entities

trait Symbol {

  /**
   * no need to expose the list of symbols that beat the current move.
   * you want to force external users of your code to use the wins function.
   */
  protected  def beats: List[Symbol]

  /**
   * This method contains belongs to the class list,
   * and it returns true if a list contains the given element,
   * false otherwise.
   * @param other
   * @return
   */
  def wins(other: Symbol):Boolean =
    beats.contains(other)

}

/**
 * Rock crushes Lizard
 * Rock crushes Scissors.
 */
case object Rock extends Symbol{
  protected val beats = List(Lizard, Scissors)
}

/**
 * Paper covers Rock
 * Paper disproves Spock
 */
case object Paper extends Symbol {
  protected  val beats = List(Rock, Spock)
}

/**
 * Scissors cuts Paper
 * Scissors decapitates Lizard
 */

case object Scissors extends Symbol {
  protected val beats = List(Paper, Lizard)
}

/**
 * Lizard posions Spock
 * Lizard eats Paper.
 */
case  object Lizard extends Symbol {
  protected val beats = List(Spock, Paper)
}


/**
 * Spock smashes Scissors
 * Spock vaporizes Rock
 */
case object Spock extends Symbol {
  protected  val beats = List(Scissors, Rock)
}

/**
 * how to parse a string into an instance of Symbol. Let’s create an object
 * to define this logic.
 */
object Symbol{
  def fromString(text:String):Symbol =
    text.trim.toLowerCase match {
      case "rock" => Rock
      case "paper" => Paper
      case "scissors" => Scissors
      case "lizard" => Lizard
      case "spock" => Spock
      /**
       * It binds the matched text to a value called unkown rather discarding it
       * because it displays it in the error message.
       */
      case unkown =>
        val errorMsg = s"Unkown symbol $unkown. " +
        "Please pick a valid symbol [Rock, Paper, Scissors, Lizard, " +
          "Spock]"
        throw new IllegalArgumentException(errorMsg)
    }
}
